package com.huilian.tool.common.utils;

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.*;

/**
 * @Author: yjzhang
 * @Date: 2020/5/22 16:02
 */

public class AES {
    public static boolean initialized = false;

    /**
     * AES解密
     * @param content 密文
     * @return
     * @throws InvalidAlgorithmParameterException
     * @throws NoSuchProviderException
     */
    public static byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte) throws InvalidAlgorithmParameterException {
        initialize();
        try {
//            Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            Key sKeySpec = new SecretKeySpec(keyByte, "AES");

            cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));// 初始化
            byte[] result = cipher.doFinal(content);
            return result;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    //密钥 (需要前端和后端保持一致)
    private static final String KEY = "huilian123456ABC";
    /**
     *    算法
     */
    private static final String ALGORITHMSTR = "AES/ECB/PKCS5Padding";
    public static String aesDecrypt(String encryptBytes) throws Exception {
        //获得密码的字节数组
        byte[] raw = KEY.getBytes();
        //根据密码生成AES密钥
        SecretKeySpec skey = new SecretKeySpec(raw, "AES");
        //根据指定算法ALGORITHM自成密码器
        Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
        //初始化密码器，第一个参数为加密(ENCRYPT_MODE)或者解密(DECRYPT_MODE)操作，第二个参数为生成的AES密钥
        cipher.init(Cipher.DECRYPT_MODE, skey);
        //把密文字符串转回密文字节数组
        byte [] encode_content = Base64.decodeBase64(encryptBytes);
        //密码器解密数据
        byte [] byte_content = cipher.doFinal(encode_content);
        //将解密后的数据转换为字符串返回
        return new String(byte_content,"utf-8");
    }

    public static void initialize(){
        if (initialized) {
            return;
        };
        Security.addProvider(new BouncyCastleProvider());
        initialized = true;
    }
    //生成iv
    public static AlgorithmParameters generateIV(byte[] iv) throws Exception{
        AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
        params.init(new IvParameterSpec(iv));
        return params;
    }
}